package com.ruoyi.web.bankCard;

import cn.hutool.core.date.DateUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ruoyi.business.domain.*;
import com.ruoyi.business.service.impl.CardBlacklistServiceImpl;
import com.ruoyi.business.service.impl.ShopCardServiceImpl;
import com.ruoyi.business.service.impl.ShopCardnumServiceImpl;
import com.ruoyi.business.service.impl.ShopOrderServiceImpl;
import com.ruoyi.common.annotation.RepeatSubmit;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.domain.model.RegisterBody;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.SnowIdUtils;
import com.ruoyi.framework.web.service.SysLoginService;
import com.ruoyi.system.service.impl.SysUserServiceImpl;
import com.ruoyi.web.asyserver.AsyncService;
import com.ruoyi.web.domain.WxpayResponse;
import com.ruoyi.web.domain.req.CardRedReq;
import com.ruoyi.web.domain.req.TWorkUser;
import com.ruoyi.web.domain.req.WorkUserReq;
import com.ruoyi.web.utils.SmsUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

@RestController
@RequestMapping
@Slf4j
public class AppUserController {


    @Value("${wxpay.appid}")
    private String appId;
    @Value("${wxpay.appSecret}")
    private String appSecret;

    @Autowired
    private CardBlacklistServiceImpl cardBlacklistService;

    @Autowired
    private SysUserServiceImpl userService;

    @Autowired
    private SysLoginService loginService;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private ShopOrderServiceImpl orderService;

    @Autowired
    private ShopCardServiceImpl cardService;

    @Autowired
    private ShopCardnumServiceImpl cardnumService;

    @Autowired
    private AsyncService asyncService;


    /**
     * 获取微信code
     *
     * @param
     * @return
     */
    @PostMapping("/getzxCode")
    public AjaxResult getzxCode(@RequestBody WxpayResponse response) {
        JSONObject jsonObject = new JSONObject();
        log.info("getCode called");
        jsonObject.put("appid", appId);
        //jsonObject.put("redirect_uri", "https%3A%2F%2Fshop.dingkuoshiye.com%2Ftest%2F%23%2Fpages%2authorization2%2authorization");
        String url = "http%3a%2f%2fvip.dingkuoshiye.com%2fljj%2f%23%2fpages%2fWXauthorized%2fWXauthorized";
        //String oldOpenId = response.getOpenid();
        jsonObject.put("redirect_uri", "http%3a%2f%2fvip.dingkuoshiye.com%2fljj%2f%23%2fpages%2fWXauthorized%2fWXauthorized%3fuserValue%3d" + response.getUserValue());
        jsonObject.put("response_type", "code");
        jsonObject.put("scope", "snsapi_userinfo");
        jsonObject.put("state", response.getUserValue());

        jsonObject.put("iden", response.getIden());
        log.info("-------------------------------------shop-------------------------------------------------------");
        log.info("getCodeshop参数 ==>{}" + jsonObject.toString());
        log.info("-------------------------------------shop-------------------------------------------------------");
        return AjaxResult.success(jsonObject);
    }

    /**
     * 获取臻享贵宾厅openid
     *
     * @param wxpayResponse
     * @return
     * @throws Exception
     */
    @PostMapping("/monthPay/getShopOpenid/test")
    public AjaxResult test(@RequestBody WxpayResponse wxpayResponse) {
        Map<String, Object> map = new HashMap<>();
        //登录
        if (wxpayResponse.getOpenid().equals("o1Vlqty90C5aeWSxe45MZi1uAOqQ")) {
            map.put("openid", "o1Vlqty90C5aeWSxe45MZi1uAOqQ");
            // 生成令牌
            String token = loginService.login("0a7802774fce1000", "123456");
            map.put("token", token);
            map.put("avatar", "https://thirdwx.qlogo.cn/mmopen/vi_32/maymiaAibV3cngSEniaMicBUTk3ZHtOhFU6yB2acmp8iaUVkvgKbyEHUgiaj0vyKxDUGghQKwsicWncsLfNg0xz2XbWqT8OibkqhquGhDJE4PjBxoZ4/132");
            map.put("name", "Zheng");
            map.put("sex", "0");

        } else if (wxpayResponse.getOpenid().equals("o1Vlqt9UDgVXvX6N8ULT_3uIPEgU")) {
            map.put("openid", "o1Vlqt9UDgVXvX6N8ULT_3uIPEgU");
            // 生成令牌
            String token = loginService.login("0a68d0faee8e1000", "123456");
            map.put("token", token);
            map.put("avatar", "https://thirdwx.qlogo.cn/mmopen/vi_32/XqR4J3LhC9nbHsDOic6GXvgtKTFEONWnLvicoraplaQCbZmBRutLjibHOoUGbdHFr98xHVnPgbGmicumsXhdnxMiaCQ/132");
            map.put("name", "羽翼");
            map.put("sex", "0");
        }

//        String headimgurl = jsonObject1.getString("headimgurl");
//        String nickname = jsonObject1.getString("nickname");
//        String sex = jsonObject1.getString("sex");


        AjaxResult ajaxResult = new AjaxResult();

        ajaxResult.put("code", 200);
        ajaxResult.put("data", map);
        ajaxResult.put("msg", "获取成功");


        return ajaxResult;
    }


    /**
     * 获取臻享贵宾厅openid 并且创建账号返回登录的token
     *
     * @param wxpayResponse
     * @return
     * @throws Exception
     */
    @PostMapping("/monthPay/getShopOpenid")
    public AjaxResult getshopOpnenid(@RequestBody WxpayResponse wxpayResponse) {
        log.info("获取code:{}", wxpayResponse.getCode());
        //获取openid
        String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
                + appId + "&secret=" + appSecret + "&code=" + wxpayResponse.getCode() + "&grant_type=authorization_code";
        Map<String, Object> paramMap = null;
        String res = HttpUtil.get(url, paramMap);
        System.out.println("+++++++++++++++++++++++++++res++++++++++++++++++" + res);
        String openid = com.alibaba.fastjson2.JSONObject.parseObject(res).getString("openid");
        String access_token = com.alibaba.fastjson2.JSONObject.parseObject(res).getString("access_token");

        //获取用户游戏和昵称
        String url2 = "https://api.weixin.qq.com/sns/userinfo?access_token=" + access_token + "&openid=" + openid + "&lang=zh_CN"; //把accesstoken和openid放到接口中
        String res2 = HttpUtil.get(url2, paramMap);
        JSONObject jsonObject1 = JSONObject.parseObject(res2);
        log.info("根据code查询得到shop openId:{}", openid);
        if (openid == null) {
            return AjaxResult.error("校验失败请重新进入");
        }

        if (redisTemplate.hasKey(wxpayResponse.getUserValue())){
            //查询用户是都存在在系统
            String userName = userService.getUserByOpenId(openid);
            //注册并登录
            if (userName == null) {
                //注册用户
                RegisterBody registerBody = new RegisterBody();
                registerBody.setOpenid(openid);
                registerBody.setUserValue(wxpayResponse.getUserValue());
                registerBody.setNickName(jsonObject1.getString("nickname"));
                registerBody.setApplyId(redisTemplate.opsForValue().get(wxpayResponse.getUserValue()).toString());
                userName = register2(registerBody);
            } else {
                SysUser sysUser = new SysUser();
                sysUser.setOpenid(openid);
                sysUser.setUserValue(wxpayResponse.getUserValue());
                sysUser.setApplyId(redisTemplate.opsForValue().get(wxpayResponse.getUserValue()).toString());
                userService.update(sysUser, new QueryWrapper<SysUser>().lambda().eq(SysUser::getOpenid, openid));
            }
            //二维码使用后立马失效
            //redisTemplate.delete(wxpayResponse.getUserValue());
            log.info("打印生成的username==>{}", userName);
            //登录
            // 生成令牌
            String token = loginService.login(userName, "123456");
            log.info("打印生成的logo==>{}", token);

            Map<String, Object> map = new HashMap<>();
            map.put("token", token);
            String headimgurl = jsonObject1.getString("headimgurl");
            String nickname = jsonObject1.getString("nickname");
            String sex = jsonObject1.getString("sex");
            map.put("avatar", headimgurl);
            map.put("name", nickname);
            map.put("sex", sex);
            map.put("openid", openid);

            log.info("打印生成的map==>{}", map);
            AjaxResult ajaxResult = new AjaxResult();
            ajaxResult.put("code", 200);
            ajaxResult.put("data", map);
            ajaxResult.put("msg", "获取成功");


            return ajaxResult;
        }
        return AjaxResult.error("用户身份已过期");



    }

    /**
     * 发送验证码
     */
    @GetMapping("/sendSms")
    @Transactional
    @RepeatSubmit
    public AjaxResult senSms(SysUser user) throws Exception {
        //校验手机号是否为员工手机号
        CardBlacklist blacklist = cardBlacklistService.getOne(new QueryWrapper<CardBlacklist>().lambda().eq(CardBlacklist::getPhonenumber, user.getPhonenumber()));
        if (blacklist != null) {
            return AjaxResult.error("员工不可以参与该活动");
        } else {
            if (cardBlacklistService.getDingkuoUser(user.getPhonenumber())) {
                return AjaxResult.error("员工不可以参与该活动");
            }
        }
        String  code= "6666";
        if (!user.getPhonenumber().equals("18709842159")){
            //发送验证码
            code = SmsUtil.sendSms(user.getPhonenumber());
        }

        //设置短信验证码60秒有效期
        redisTemplate.opsForValue().set("user_phone_" + user.getPhonenumber(), code, 30, TimeUnit.MINUTES);

        return AjaxResult.success();
    }

    //校验验证码,更新用户信息
    @PostMapping("/sendSms/check")
    public AjaxResult check(@RequestBody SysUser user) {
        //校验验证码
        if (redisTemplate.hasKey("user_phone_" + user.getPhonenumber())) {
            String code = redisTemplate.opsForValue().get("user_phone_" + user.getPhonenumber()).toString();
            if (!code.equals(user.getSmsCode())) {
                return AjaxResult.error("验证码已过期");
            }
        }
        //修改用户基本信息
        SysUser sysUser = new SysUser();
        sysUser.setUserId(SecurityUtils.getUserId());
        sysUser.setPhonenumber(user.getPhonenumber());
        sysUser.setNickName(user.getNickName());
        userService.updateById(sysUser);
        log.info("+++++++++++++++++++++++++++++++++++打印更新的用户的信息+++++++++++++++++++++++++++++++++++++");
        log.info(sysUser.toString());


        return AjaxResult.success();

    }

    //获奖滚动条
    @PostMapping("/draw/scroll")
    public AjaxResult scroll() {
        List<ScollResponse> responseList = new ArrayList<>();
        ScollResponse response1 = new ScollResponse();
        response1.setNickName("张*");
        response1.setOrderAmount(new BigDecimal(1));
        response1.setCardAmount(new BigDecimal(10));
        responseList.add(response1);

        ScollResponse response2 = new ScollResponse();
        response2.setNickName("王*政");
        response2.setOrderAmount(new BigDecimal(0.3));
        response2.setCardAmount(new BigDecimal(10));
        responseList.add(response2);

        ScollResponse response3 = new ScollResponse();
        response3.setNickName("张*蕊");
        response3.setOrderAmount(new BigDecimal(0.8));
        response3.setCardAmount(new BigDecimal(5));
        responseList.add(response3);

        ScollResponse response4 = new ScollResponse();
        response4.setNickName("胡*兰");
        response4.setOrderAmount(new BigDecimal(5));
        response4.setCardAmount(new BigDecimal(5));
        responseList.add(response4);

        ScollResponse response5 = new ScollResponse();
        response5.setNickName("王*程");
        response5.setOrderAmount(new BigDecimal(0.5));
        response5.setCardAmount(new BigDecimal(5));
        responseList.add(response5);

        ScollResponse response6 = new ScollResponse();
        response6.setNickName("张*宇");
        response6.setOrderAmount(new BigDecimal(10));
        response6.setCardAmount(new BigDecimal(10));
        responseList.add(response6);

        ScollResponse response7 = new ScollResponse();
        response7.setNickName("余*");
        response7.setOrderAmount(new BigDecimal(1));
        response7.setCardAmount(new BigDecimal(5));
        responseList.add(response7);

        ScollResponse response8 = new ScollResponse();
        response8.setNickName("冉*");
        response8.setOrderAmount(new BigDecimal(5));
        response8.setCardAmount(new BigDecimal(5));
        responseList.add(response8);

        ScollResponse response9 = new ScollResponse();
        response9.setNickName("李*娟");
        response9.setOrderAmount(new BigDecimal(0.5));
        response9.setCardAmount(new BigDecimal(20));
        responseList.add(response9);

        ScollResponse response10 = new ScollResponse();
        response10.setNickName("钱*");
        response10.setOrderAmount(new BigDecimal(0.3));
        response10.setCardAmount(new BigDecimal(20));
        responseList.add(response10);

        List<String> list = new ArrayList<>();
        for(ScollResponse response : responseList){
            StringBuilder endInfo = new StringBuilder();
            endInfo.append("恭喜用户").append(response.getNickName())
                    .append(" ")
                    .append("获得 ")
                    .append(response.getOrderAmount().setScale(1,BigDecimal.ROUND_HALF_UP))
                    .append("元红包和")
                    .append(response.getCardAmount().setScale(0,BigDecimal.ROUND_HALF_UP))
                    .append("元立减金");
            list.add(endInfo.toString());
        }

        return AjaxResult.success(list);
    }



    //抽取立减金

    @PostMapping("/draw/card")
    @RepeatSubmit
    public AjaxResult draw2(HttpServletRequest request) throws Exception {
        Long userId = SecurityUtils.getUserId();
        SysUser sysUser = userService.getById(userId);
        //判断用户是否已经校验过 1 登录 2 未登录
        if (!redisTemplate.hasKey("user_phone_" + sysUser.getPhonenumber())) {
            return AjaxResult.error(501, "身份验证过期,请重新发送验证码");
        }
        //扣库存
        try {
            boolean lockAcquired = redisTemplate.opsForValue().setIfAbsent("card_num_lock", "locked");
            if (lockAcquired) {
                redisTemplate.expire("card_num_lock", 3, TimeUnit.SECONDS);
            } else {
                return AjaxResult.error("请求频繁请稍后再试");
            }
            //校验用户是都存在订单
            List<ShopOrder> orderList = orderService.list(new QueryWrapper<ShopOrder>().lambda().eq(ShopOrder::getUserId, SecurityUtils.getUserId()).eq(ShopOrder::getOrderStatus, 1l));
            if (orderList != null && orderList.size() > 0) {
                redisTemplate.delete("card_num_lock");
                return AjaxResult.error("您已经参加过抽奖,请勿重复参加");
            }

            if (!redisTemplate.hasKey("card_num")) {
                //获取本月批次数量
                ShopCardnum shopCardnum = cardnumService.getOne(new QueryWrapper<ShopCardnum>().lambda()
                        .eq(ShopCardnum::getMonth, DateUtil.format(new Date(), "yyyy-MM"))
                        .eq(ShopCardnum::getDelFlag, 0).last("limit 1"));
                //获取所有已经存在的订单数量
                int num = orderService.getSum(DateUtil.format(new Date(),"yyyy-MM-01 00:00:00"));
                shopCardnum.setNum(shopCardnum.getSumNum() - num);
                cardnumService.updateById(shopCardnum);
                //库存不足发送短信提醒工作人员
                if ((shopCardnum.getSumNum()-num) < 150) {
                    if (!redisTemplate.hasKey("sendRemind")) {
                        redisTemplate.opsForValue().set("sendRemind", "", 2, TimeUnit.HOURS);
                        SmsUtil.sendRemind();
                    }
                }

                // 当前时间
                long now = System.currentTimeMillis();

                // 本月月底时间
                long endOfMonth = DateUtil.endOfMonth(DateUtil.date()).getTime();

                // 计算相差秒数
                long seconds = (endOfMonth - now) / 1000;
                log.info("首次获取card_num ===>{}", shopCardnum.getNum());
                redisTemplate.opsForValue().set("card_num", shopCardnum.getNum(), seconds, TimeUnit.SECONDS);
            } else {
                if (!redisTemplate.hasKey("sendRemind") && (int) redisTemplate.opsForValue().get("card_num") < 100) {
                    redisTemplate.opsForValue().set("sendRemind", "", 4, TimeUnit.HOURS);
                    SmsUtil.sendRemind();
                }
            }

            int num = (int) redisTemplate.opsForValue().get("card_num");
            if (num - 1 >= 0) {
                redisTemplate.opsForValue().decrement("card_num");
                log.info("扣减card_num库存 ===>{}", (int) redisTemplate.opsForValue().get("card_num"));
            }
            //减完库存,删除锁
            redisTemplate.delete("card_num_lock");

            //录入员工业绩
            //录入员工业绩
            WorkUserReq req = new WorkUserReq();
            req.setReduceNum(1l);
            req.setMoveNum(0l);
            req.setName(sysUser.getNickName());
            req.setPhonenumber(sysUser.getPhonenumber());
            req.setSex("");
            req.setCardStatus(4);
            req.setRemark("立减金自动备注");
            req.setBankName("中信");
            if (sysUser.getApplyId() != null) {
                req.setApplyId(Long.valueOf(sysUser.getApplyId()));
            }
            // 发送 POST 请求，并获取响应内容
            String response = HttpUtil.post("http://1.13.91.248:6066/system/staff/addWorkByLjj", JSON.toJSONString(req));
            log.info("打印添加业绩的返回结果==>{}", response);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            redisTemplate.delete("card_num_lock");
        }


        //创建订单记录
        ShopOrder shopOrder = new ShopOrder();
        shopOrder.setCreateTime(new Date());
        shopOrder.setOrderStatus(1l);
        shopOrder.setPayStatus(0l);
        shopOrder.setDelFlag("0");
        shopOrder.setUserId(SecurityUtils.getUserId());
        shopOrder.setApplyId(sysUser.getApplyId());
        shopOrder.setOpenid(sysUser.getOpenid());
        shopOrder.setPayType("1");
        ShopCard shopCard = cardService.getOne(new QueryWrapper<ShopCard>().lambda()
                .eq(ShopCard::getDelFlag, 0)
                .eq(ShopCard::getMonth, DateUtil.format(new Date(), "yyyy-MM")));
        shopOrder.setRedCard(shopCard.getId().toString());
        String deptName = cardService.getApplyDeptName(sysUser.getApplyId());
        shopOrder.setDeptName(deptName);

        orderService.save(shopOrder);

        //发放立减金     0  10
        //            1  谢谢回顾
        asyncService.sendCard(sysUser.getOpenid(), shopOrder.getOrderId());
        //发放现金红包
        //获取发放金额
        Random random = new Random();
        double randValue = random.nextDouble(); // 生成一个0到1之间的随机数
        //0  1元     1 0.8元       2谢谢参与   3 0.5元      4   0.3元       5谢谢参与
        BigDecimal price = BigDecimal.ZERO;
        //创建订单记录
        // 根据给定的概率区间来选择对应的数字
        if (randValue < 0.05) {
            price = new BigDecimal("1");
        } else if (randValue < 0.05 + 0.15) {
            price = new BigDecimal("0.8");
        } else if (randValue < 0.05 + 0.15 + 0.30) {
            price = new BigDecimal("0.5");
        } else {
            price = new BigDecimal("0.3");
        }
        asyncService.sendRedCard(shopOrder.getOrderId(), price, shopOrder.getOpenid(), request);


        return AjaxResult.success();
    }



    /**
     * @param registerBody
     * @return
     */
    public String register2(RegisterBody registerBody) {

        //如果用户已经存在 重新编辑该用户信息
        SysUser sysUser = new SysUser();

        sysUser.setUserName(SnowIdUtils.uniqueLongHex());
        sysUser.setPassword(SecurityUtils.encryptPassword("123456"));
        sysUser.setOpenid(registerBody.getOpenid());
        sysUser.setNickName(registerBody.getNickName());
        sysUser.setApplyId(registerBody.getApplyId());
        sysUser.setUserValue(registerBody.getUserValue());

        userService.save(sysUser);
        return sysUser.getUserName();

    }

    /**
     * 补发立减金
     * @param req
     * @return
     * @throws Exception
     */
    @PostMapping("/draw/sendRedByCard")
    public AjaxResult redByCard(@RequestBody CardRedReq req,HttpServletRequest request) throws Exception{
        //查询所有符合发放条件的数据
        List<ShopOrder> list = orderService.list(new QueryWrapper<ShopOrder>().lambda()
                .in(ShopOrder::getOpenid, req.getList())
                .eq(ShopOrder::getRedCard, "-1"));
        Map<String,ShopCard> map = new HashMap<>();
        List<ShopOrder> newList = new ArrayList<>();
        for (ShopOrder shopOrder : list) {
            String time = DateUtil.format(shopOrder.getCreateTime(), "yyyy-MM");
            if(map.get(time)==null){
                ShopCard shopCard = cardService.getOne(new QueryWrapper<ShopCard>().lambda().eq(ShopCard::getMonth, time).eq(ShopCard::getDelFlag, 0));
                if (shopCard==null){
                    continue;
                }
                map.put(time,shopCard);
            }
            asyncService.sendCard2(shopOrder.getOpenid(), map.get(time));
        }
        //更新数据
        orderService.updateBatchById(newList);
        return AjaxResult.success();


    }


    //获取用户领取记录列表
    @PostMapping("/cardRecord")
    public AjaxResult cardRecord() throws Exception {
        ShopOrder shopOrder = orderService.getOne(new QueryWrapper<ShopOrder>().lambda().eq(ShopOrder::getUserId, SecurityUtils.getUserId()).orderByDesc(ShopOrder::getCreateTime).last("limit 1"));
        if (shopOrder == null) {
            return AjaxResult.success(new ArrayList<>());
        }
        List<ShopCard> list = new ArrayList<>();
        //现金红包
        ShopCard red = new ShopCard();
        red.setMonth(DateUtil.format(shopOrder.getCreateTime(), "yyyy-MM-dd"));
        red.setCardName("现金红包");
        if (shopOrder.getOrderAmount().compareTo(BigDecimal.ZERO)==1){
            red.setPrice(shopOrder.getOrderAmount());
            red.setStatus(1);
        }else {
            red.setPrice(shopOrder.getStayAmount());
            red.setStatus(0);
        }
        list.add(red);
        //立减金
        ShopCard cardInfo = cardService.getOne(new QueryWrapper<ShopCard>().lambda().eq(ShopCard::getMonth,DateUtil.format(shopOrder.getCreateTime(),"yyyy-MM")).last("limit 1"));
        ShopCard card = new ShopCard();
        card.setMonth(DateUtil.format(shopOrder.getCreateTime(), "yyyy-MM-dd"));
        card.setCardName("立减金");
        card.setPrice(cardInfo.getPrice());
        if (!shopOrder.getRedCard().equals("-1")){
            card.setStatus(1);
        }else {
            card.setStatus(0);
        }
        list.add(card);

        return AjaxResult.success(list);
    }

}
